﻿using Common.Communication;
using Common.Device;
using Common.Device.DeviceDb;
using Common.Device.Enums;
using Common.Device.Interfaces;
using Common.Device.Models;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace AnGuiYi.JueYuanNaiYa
{
    public class TH2689SerialPort : SerialPortBase, IJueYuanNaiYa
    {
        public string Name { get; set; }
        public TH2689SerialPort(UseDevice device) : base(device.port, Convert.ToInt32(device.parameter), timeout: 1500)
        {
            Name = device.name;
        }

        public Result<List<JueYuanNaiYaResult>> SetTest(Common.Device.Models.JueYuanNaiYa parameter)
        {
            lock (this)
            {
                var result = new Result<List<JueYuanNaiYaResult>>(new List<JueYuanNaiYaResult>());
                var write = new Result();
                var read = new Result<string>();
                AppendInfo(Name, $"设置蜂鸣器OFF");
                write = Write(CmdSetBeep("OFF"));
                if (!write.IsSucceed)
                {
                    result.IsSucceed = false;
                    result.Err = "设置蜂鸣器失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                Thread.Sleep(200);
                //发送指令并返回
                read = WriteThenRead(CmdGetBeep,wait:100);
                if (!read.IsSucceed || !read.Value.Contains("0"))
                {
                    result.IsSucceed = false;
                    result.Err = "设置蜂鸣器失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                AppendInfo(Name, "设置蜂鸣器成功");
                AppendInfo(Name, $"设置测试参数");
                string type = "";
                switch (parameter.mode)
                {
                    case AnGuiYiEnum.TestMode.绝缘电阻:
                        result.Err = "不支持绝缘电阻";
                        result.IsSucceed = false;
                        return result.EndTime();
                    case AnGuiYiEnum.TestMode.直流耐压:
                        result.Err = "不支持直流耐压";
                        result.IsSucceed = false;
                        return result.EndTime();
                    case AnGuiYiEnum.TestMode.交流耐压:
                        result.Err = "不支持交流耐压";
                        result.IsSucceed = false;
                        return result.EndTime();
                    case AnGuiYiEnum.TestMode.漏电流:
                        type = "LCTest";
                        break;
                    default:
                        break;
                }
                if (parameter.mode == AnGuiYiEnum.TestMode.漏电流)
                {
                    AppendInfo(Name, $"设置测试类型SEQ");
                    write = Write(CmdSetLcFuc);
                    if (!write.IsSucceed)
                    {
                        result.IsSucceed = false;
                        result.Err = "设置测试类型失败";
                        AppendTip(Name, result.Err);
                        return result.EndTime();
                    }
                    Thread.Sleep(200);
                    //发送指令并返回
                    read = WriteThenRead(CmdGetLcFuc, wait: 100);
                    if (!read.IsSucceed || !read.Value.Contains("SEQ"))
                    {
                        result.IsSucceed = false;
                        result.Err = "设置测试类型失败";
                        AppendTip(Name, result.Err);
                        return result.EndTime();
                    }
                    AppendInfo(Name, $"设置电压{parameter.电压值}kV");
                    write = Write(CmdSetVol(parameter.电压值*1000, type));
                    if (!write.IsSucceed)
                    {
                        result.IsSucceed = false;
                        result.Err = "设置电压失败";
                        AppendTip(Name, result.Err);
                        return result.EndTime();
                    }
                    Thread.Sleep(200);
                    read = WriteThenRead(CmdGetVol(type), wait: 100);
                    if (!read.IsSucceed || !double.TryParse(read.Value, out double v) || v != parameter.电压值)
                    {
                        result.IsSucceed = false;
                        result.Err = "设置电压失败";
                        AppendTip(Name, result.Err);
                        return result.EndTime();
                    }
                    AppendInfo(Name, $"设置电流{parameter.电流值}A");
                    write = Write(CmdSetCur(parameter.电流值, type));
                    if (!write.IsSucceed)
                    {
                        result.IsSucceed = false;
                        result.Err = "设置电流失败";
                        AppendTip(Name, result.Err);
                        return result.EndTime();
                    }
                    Thread.Sleep(200);
                    read = WriteThenRead(CmdGetCur(type), wait: 100);
                    if (!read.IsSucceed || !double.TryParse(read.Value, out double c) || c != parameter.电流值)
                    {
                        result.IsSucceed = false;
                        result.Err = "设置电流失败";
                        AppendTip(Name, result.Err);
                        return result.EndTime();
                    }
                    AppendInfo(Name, $"设置自动换挡");
                    write = Write(CmdSetLcAutoRange);
                    if (!write.IsSucceed)
                    {
                        result.IsSucceed = false;
                        result.Err = "设置电流失败";
                        AppendTip(Name, result.Err);
                        return result.EndTime();
                    }
                    Thread.Sleep(200);
                    read = WriteThenRead(CmdGetLcRange, wait: 100);
                    if (!read.IsSucceed || !read.Value.Contains("1"))
                    {
                        result.IsSucceed = false;
                        result.Err = "设置电流失败";
                        AppendTip(Name, result.Err);
                        return result.EndTime();
                    }
                    AppendInfo(Name, $"设置测量速度中档");
                    write = Write(CmdSetLcSpeed("SLOW"));//{FAST | MEDium | SLOW} 
                    if (!write.IsSucceed)
                    {
                        result.IsSucceed = false;
                        result.Err = "设置测量速度中档失败";
                        AppendTip(Name, result.Err);
                        return result.EndTime();
                    }
                    Thread.Sleep(200);
                    read = WriteThenRead(CmdGetLcSpeed, wait: 100);
                    if (!read.IsSucceed || !read.Value.Contains("SLOW"))
                    {
                        result.IsSucceed = false;
                        result.Err = "设置测量速度中档失败";
                        AppendTip(Name, result.Err);
                        return result.EndTime();
                    }

                    AppendInfo(Name, $"设置充电时间{parameter.上升时间}s");
                    write = Write(CmdSetLcChgTime(parameter.上升时间));
                    if (!write.IsSucceed)
                    {
                        result.IsSucceed = false;
                        result.Err = "设置充电时间失败";
                        AppendTip(Name, result.Err);
                        return result.EndTime();
                    }
                    Thread.Sleep(200);
                    read = WriteThenRead(CmdGetLcChgTime, wait: 100);
                    if (!read.IsSucceed || !double.TryParse(read.Value, out double ut) || ut != parameter.上升时间)
                    {
                        result.IsSucceed = false;
                        result.Err = "设置上升时间失败";
                        AppendTip(Name, result.Err);
                        return result.EndTime();
                    }
                    AppendInfo(Name, $"设置延迟时间{parameter.测试时间}s");
                    write = Write(CmdSetLcDwellTime(parameter.测试时间));
                    if (!write.IsSucceed)
                    {
                        result.IsSucceed = false;
                        result.Err = "设置延迟时间失败";
                        AppendTip(Name, result.Err);
                        return result.EndTime();
                    }
                    Thread.Sleep(200);
                    read = WriteThenRead(CmdGetLcDwellTime, wait: 100);
                    if (!read.IsSucceed || !double.TryParse(read.Value, out double kt) || kt != parameter.测试时间)
                    {
                        result.IsSucceed = false;
                        result.Err = "设置保持时间失败";
                        AppendTip(Name, result.Err);
                        return result.EndTime();
                    }
                }
                AppendInfo(Name, $"设置测试参数成功");
                write = Write(CmdSetBus);
                if (!write.IsSucceed)
                {
                    result.IsSucceed = false;
                    result.Err = "开始测试失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                Thread.Sleep(200);
                read = WriteThenRead(CmdGetBus, wait: 100);
                if (!read.IsSucceed || !read.Value.Contains("BUS"))
                {
                    Write(CmdStop);
                    result.IsSucceed = false;
                    result.Err = "开始测试失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                AppendInfo(Name, $"设置测试参数成功");
                AppendInfo(Name, $"开始测试");
                List<string> temps = new List<string>();
                List<string> vols = new List<string>();
                List<string> units = new List<string>();
                write = Write(CmdStart);
                if (!write.IsSucceed)
                {
                    result.IsSucceed = false;
                    result.Err = "开始测试失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                Thread.Sleep(200);
                read = WriteThenRead(CmdLcState, wait: 100);
                if (!read.IsSucceed || !read.Value.Contains("CHG"))
                {
                    result.IsSucceed = false;
                    result.Err = "开始测试失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                DateTime testTime = DateTime.Now.AddSeconds(parameter.上升时间 + parameter.测试时间 + 30);
                Thread.Sleep((int)(parameter.上升时间 + parameter.测试时间) * 1000);
                while (DateTime.Now < testTime)
                {
                    Thread.Sleep(500);
                    read = WriteThenRead(CmdLcState, wait: 100);
                    if (read.IsSucceed && read.Value.Contains("DCHG"))
                    {
                        break;
                    }
                    if (DeviceService.IsStop)
                    {
                        Write(CmdStop);
                        result.IsSucceed = false;
                        result.Err = "停止测试";
                        AppendTip(Name, result.Err);
                        return result.EndTime();
                    }
                    //todo 失败停止
                }
                read = WriteThenRead(CmdLcMeasure, wait: 100);
                if (!read.IsSucceed || !double.TryParse(read.Value, out double value))
                {
                    Write(CmdStop);
                    result.IsSucceed = false;
                    result.Err = "读取失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                JueYuanNaiYaResult jueYuanNai = new JueYuanNaiYaResult()
                {
                    type = parameter.mode.ToString(),
                    value = parameter.电压值 + "V," + value + "A",
                    isPass = value >= parameter.下限值 && value <= parameter.上限值
                };
                result.Value.Add(jueYuanNai);
                AppendResult(Name, jueYuanNai.type + "," + jueYuanNai.value + "," + jueYuanNai.isPass);
                if (value < parameter.下限值 || value > parameter.上限值)
                {
                    result.IsSucceed = false;
                    result.Err = "测试未通过";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                return result.EndTime();
            }
        }
        public Result<bool> StopTest()
        {
            lock (this)
            {
                var result = new Result<bool>();
                var write = new Result();
                AppendInfo(Name, $"停止测试");
                List<string> temps = new List<string>();
                write = Write(CmdStop);
                if (!write.IsSucceed)
                {
                    result.IsSucceed = false;
                    result.Err = "停止测试失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                AppendInfo(Name, $"停止测试成功");
                return result.EndTime();
            }
        }
        string CmdId => "*IDN?\n";
        string CmdSetBeep(string beep) { return $":SYSTem:BEEPer:STATe {beep}\n"; }
        string CmdGetBeep => ":SYSTem:BEEPer:STATe?\n";
        string CmdSetVol(double vol, string type) { return $":{type}:SOURce:VOLTage {vol}\n"; }
        string CmdGetVol(string type) { return $":{type}:SOURce:VOLTage?\n"; }
        string CmdSetCur(double cur, string type) { return $":{type}:SOURce:CURRent {cur}\n"; }
        string CmdGetCur(string type) { return $":{type}:SOURce:CURRent?\n"; }
        string CmdSetLcFuc => $":LCTest:CONFigure:FUNCtion SEQ\n"; 
        string CmdGetLcFuc => $":LCTest:CONFigure:FUNCtion?\n"; 
        string CmdSetLcSpeed(string speed) { return $":LCTest:CONFigure:SPEed {speed}\n"; } 
        string CmdGetLcSpeed => $":LCTest:CONFigure:SPEed?\n"; 
        string CmdSetLcAutoRange => $":LCTest:CONFigure:RANGe:AUTO ON\n"; 
        string CmdGetLcRange => $":LCTest:CONFigure:RANGe:AUTO?\n";
        string CmdSetLcChgTime(double time) { return $":LCTest:CONFigure:CHGTime {time}\n"; }
        string CmdGetLcChgTime => $":LCTest:CONFigure:CHGTime?\n";
        string CmdSetLcDwellTime(double time) { return $":LCTest:CONFigure:DWELl {time}\n"; }
        string CmdGetLcDwellTime => $":LCTest:CONFigure:DWELl?\n";
        string CmdStart => ":TRIGger:IMMediate\n";
        string CmdStop => ":ABORt\n";
        string CmdLcState => ":LCTest:MEASure:STATe?\n";
        string CmdLcMeasure => ":LCTest:MEASure:LC?\n";
        string CmdSetBus => ":TRIGger:SOURce BUS\n";
        string CmdGetBus => ":TRIGger:SOURce?\n";
    }
}
